package com.powernode.ssm.service;

import com.powernode.ssm.pojo.po.UserLoginAttempt;

import java.time.LocalDateTime;

/**
 * Service 接口：提供基于 user_login_attempt 表的 IP 登录频控能力（用于 Redis 降级场景）
 * <p>
 * 主要功能包括：
 * - 查询某个 IP 的登录尝试记录
 * - 判断该 IP 是否允许登录（是否超频、是否被封禁）
 * - 记录一次登录尝试（用于统计短期/长期次数，可能触发封禁）
 * - 封禁 IP（设置 is_blocked = 1，记录封禁时间）
 * - 解封 IP（设置 is_blocked = 0，清除封禁时间）
 * - 重置短期/长期尝试窗口（如超时后自动重置计数）
 * </p>
 */
public interface UserLoginAttemptService {

    /**
     * 根据 IP 查询对应的登录尝试记录
     *
     * @param ip 客户端 IP 地址
     * @return UserLoginAttempt 对象，如果不存在则返回 null
     */
    UserLoginAttempt findByIp(String ip);

    /**
     * 判断当前 IP 是否允许登录
     * <p>
     * 判断逻辑包括：
     * 1. 是否已被封禁且未过期
     * 2. 短期尝试次数（如 60 秒内）是否超过限制
     * 3. 长期尝试次数（如 10 分钟内）是否超过限制
     * </p>
     *
     * @param ip 客户端 IP 地址
     * @return true 表示允许登录，false 表示不允许（超频或被封禁）
     */
    boolean isLoginAllowed(String ip);

    /**
     * 记录一次登录尝试
     * <p>
     * 作用：更新该 IP 的短期/长期尝试次数，可能会触发封禁逻辑
     * </p>
     *
     * @param ip 客户端 IP 地址
     */
    void recordLoginAttempt(String ip);

    /**
     * 封禁指定的 IP 地址
     * <p>
     * 设置 is_blocked = 1，并记录封禁过期时间（如 1 小时后解封）
     * </p>
     *
     * @param attempt 当前登录尝试记录（可为 null，内部会构造默认值）
     * @param ip      客户端 IP 地址
     * @param now     当前时间，用于计算过期时间
     */
    void blockIp(UserLoginAttempt attempt, String ip, LocalDateTime now);

    /**
     * 重置封禁状态（解封 IP）
     * <p>
     * 设置 is_blocked = 0，并清除 block_expire_time
     * </p>
     *
     * @param ip   客户端 IP 地址
     * @param now  当前时间
     */
    void resetBlockStatus(String ip, LocalDateTime now);

    /**
     * 重置短期尝试窗口（如 60 秒窗口过期后，重置短期尝试次数）
     *
     * @param ip   客户端 IP 地址
     * @param now  当前时间
     */
    void resetShortWindow(String ip, LocalDateTime now);

    /**
     * 重置长期尝试窗口（如 10 分钟窗口过期后，重置长期尝试次数）
     *
     * @param ip   客户端 IP 地址
     * @param now  当前时间
     */
    void resetLongWindow(String ip, LocalDateTime now);
}